import React, { PureComponent } from 'react';
import { Card, Button, message, Spin } from 'antd';
import { Map } from 'react-amap';
import router from 'umi/router';
import { connect } from 'dva';
import moment from 'moment/moment';

class Location extends PureComponent<any, any> {
  constructor(props: any) {
    super(props);
    this.state = {
      vin: null,
      btnLoading: false,
      count: 0,
      display: false,
      spinning: false,
      record: null,
    };
  }

  areaStyle = {
    fillOpacity: 0.7,
    fillColor: '#4B9248',
    strokeStyle: 'solid',
    strokeColor: '#006633',
  };

  resolve;
  mapPromise = new Promise(resolve => (this.resolve = resolve));

  // 初始化围栏
  initFence = async (fenceId: any) => {
    if (!fenceId) {
      return;
    }
    const { ins } = await this.mapPromise;
    const res = await this.props.dispatch({
      type: 'http/getData',
      payload: {
        url: '/electricfence/getfencedetail',
        fenceId: fenceId,
      },
    });

    if (res.statusCode === '0') {
      const data = res.data;
      if (data.fenceType) {
        // 行政区围栏
        const dist = data.districtList ? data.districtList[0] || {} : {};
        const code = dist.areaCode || dist.cityCode || dist.provinceCode;
        if (!code) {
          return;
        }
        const json = await fetch(`https://geo.datav.aliyun.com/areas_v3/bound/${code}.json`).then(
          e => {
            return e.json();
          },
        );
        const geojson = new AMap.GeoJSON({
          geoJSON: json,
        });
        ins.add(geojson);
      } else {
        // 地图回显 - 圆
        if (data.circleList) {
          data.circleList.forEach(e => {
            const circle = {
              obj: new AMap.Circle({
                map: ins,
                ...this.areaStyle,
                radius: e.radius,
                center: [e.centerLng, e.centerLat],
              } as any),
            };
          });
        }

        // 地图回显 - 多边形
        if (data.polygonList) {
          data.polygonList.forEach(e => {
            const polygon = {
              obj: new AMap.Polygon({
                map: ins,
                ...this.areaStyle,
                path: e.pointInfos.map(item => new AMap.LngLat(item.lng, item.lat)),
                // draggable: true,
              } as any),
            };
          });
        }
      }

      ins.setFitView();
    }
  };

  componentDidMount() {
    this.open();
  }

  componentWillUnmount() {
    if (this.sendOrderTimer) {
      clearInterval(this.sendOrderTimer);
      this.sendOrderTimer = null;
    }
  }

  open = () => {
    // 初始化围栏
    this.initFence(this.props.location.query.fenceId);

    // 初始化坐标点
    let vin = this.props.location.query.vin;
    //TO-DO 先用有车况数据的测试VIN
    // vin = 'LGJE5FE01LM814641';
    // vin = 'LGJE1EE03LM936000';
    this.setState({ vin: vin, spinning: true });
    const { dispatch } = this.props;
    dispatch({
      type: 'fenceVehicleMng/getDataWithRes',
      payload: {
        url: '/electricfence/getvehiclelocation',
        vin: vin,
      },
      callback: (res: any) => {
        this.setState({ display: true }, async () => {
          if (res.statusCode == '0') {
            const record = res.data;
            if (record && record.lon && record.lat) {
              this.drawMarker(this.bd_decrypt(record.lon, record.lat));
            }
            this.setState({ record });
          }
        });
      },
    });
  };

  refreshLocation = () => {
    const { vin } = this.state;
    const { dispatch } = this.props;
    dispatch({
      type: 'fenceVehicleMng/getData',
      payload: {
        url: '/electricfence/getvehiclelocation',
        vin: vin,
      },
      callback: (res: any) => {
        this.setState({ record: res.data }, () => {
          if (res.data && res.data.lon && res.data.lat) {
            message.success('获取车辆位置成功');

            this.drawMarker(this.bd_decrypt(res.data.lon, res.data.lat));
          } else {
            message.error('获取车辆位置失败');
            this.drawMarker(null);
          }
        });
      },
    });
  };

  close = () => {
    if (this.sendOrderTimer) {
      clearInterval(this.sendOrderTimer);
      this.sendOrderTimer = null;
    }
    this.setState({ display: false }, () => {
      this.setState(
        {
          vin: null,
          btnLoading: false,
          count: 0,
          spinning: false,
          record: null,
        },
        () => {
          router.replace(`${self === top ? '' : '/external'}/electricFence/fenceVehicleMng`);
        },
      );
    });
  };

  sendOrder = async () => {
    this.setState({ btnLoading: true });
    const result = await this.props.dispatch({
      type: 'fenceVehicleMng/getData',
      payload: {
        url: '/electricfence/sendvehiclelocation',
        vin: this.state.vin,
      },
    });
    if (result.statusCode !== '0') {
      this.setState({ btnLoading: false });
      return;
    }
    message.success('下发指令成功！');
    let count = 16; //指令下发15秒后再获取车辆位置
    this.sendOrderTimer = setInterval(() => {
      count--;
      this.setState({ count });
      if (count === 0) {
        this.setState({
          btnLoading: false,
        });
        clearInterval(this.sendOrderTimer);
        this.refreshLocation();
      }
    }, 1000);
  };

  drawMarker = async (lnglat: any) => {
    const { ins } = await this.mapPromise;
    // ins.clearMap();
    ins.remove(ins.getAllOverlays('marker'));
    if (lnglat == null) {
      return;
    }
    ins.setZoomAndCenter(16, lnglat);
    new AMap.Marker({
      map: ins,
      position: lnglat,
      icon: require('../../../assets/car_location.png'),
      offset: new AMap.Pixel(-20, -50),
      autoRotation: true,
    });
  };

  /**
   * 百度坐标转高德坐标
   */
  bd_decrypt = (lon: any, lat: any) => {
    let X_PI = (Math.PI * 3000.0) / 180.0;
    let x = lon - 0.0065;
    let y = lat - 0.006;
    let z = Math.sqrt(x * x + y * y) - 0.00002 * Math.sin(y * X_PI);
    let theta = Math.atan2(y, x) - 0.000003 * Math.cos(x * X_PI);
    let gg_lng = z * Math.cos(theta);
    let gg_lat = z * Math.sin(theta);
    return [gg_lng, gg_lat];
  };

  render() {
    const { btnLoading, count, spinning, record } = this.state;
    return (
      <Card
        title="车辆位置"
        onClose={this.close}
        bodyStyle={{ padding: '12px 24px' }}
        width={800}
        extra={
          <Button size="small" onClick={this.close}>
            关闭
          </Button>
        }
      >
        <Spin spinning={spinning}>
          <div>
            <Button size="small" type="primary" onClick={this.sendOrder} loading={btnLoading}>
              {count ? `获取车辆位置(${count}s)` : '查询位置'}
            </Button>
            {record && record.address ? (
              <span style={{ marginLeft: 10 }}>车辆位置 : {record.address}</span>
            ) : null}
            <div
              style={{
                width: '100%',
                height: 'calc(100vh - 250px)',
                border: '1px solid #d9d9d9',
                marginTop: 12,
              }}
            >
              {this.state.display ? (
                <Map
                  ak={'19dbf6ffd63917bac5a923432ed8ca7a'}
                  events={{
                    created: async ins => {
                      await Promise.all([
                        // new Promise(resolve => window.AMap.plugin('AMap.MouseTool', resolve)),
                        // new Promise(resolve => window.AMap.plugin('AMap.CircleEditor', resolve)),
                        // new Promise(resolve => window.AMap.plugin('AMap.PolyEditor', resolve)),
                        // new Promise(resolve => window.AMap.plugin('AMap.Geocoder', resolve)),
                        // new Promise(resolve => window.AMap.plugin('AMap.Autocomplete', resolve)),
                      ]);
                      this.resolve({
                        ins,
                        // tool: new window.AMap.MouseTool(ins),
                        // geocoder: new window.AMap.Geocoder({}),
                      });
                      this.setState({ spinning: false });
                    },
                  }}
                />
              ) : null}
            </div>
          </div>
        </Spin>
      </Card>
    );
  }
}
export default connect()(Location);
